<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="${pageContext.request.contextPath}/style/ol.css" />
    <script src="${pageContext.request.contextPath}/js/jquery-1.11.3.min.js"></script>
    <script src="${pageContext.request.contextPath}/js/ol.js"></script>
    <style>
      * {
        padding: 0;
        margin: 0;
      }

      #layerControl {
        border-radius: 4px;
        padding-top: 10px;
        padding-bottom: 10px;
        padding-left: 20px;
        width: 190px;
        position: absolute;
        top: 20px;
        right: 20px;
        background: rgba(169, 169, 169,0.3);
        /* background: url(${pageContext.request.contextPath}/images/light.png) no-repeat;
        box-shadow: inset 0px 2px 118px #41a2ff; */
      }

      #measureType {
        border-radius: 4px;
        padding: 10px;
        text-align: center;
        width: 190px;
        position: absolute;
        top: 200px;
        right: 20px;
        background: rgba(169, 169, 169,0.3);;
        /* background: url(${pageContext.request.contextPath}/images/light.png) no-repeat center;
        background-size: 100% 100%;
        box-shadow: inset 0px 2px 118px #41a2ff; */
      }

      .tooltip {
        position: relative;
        background: rgba(0, 0, 0, 0.5);
        border-radius: 4px;
        color: white;
        padding: 4px 8px;
        opacity: 0.7;
        white-space: nowrap;
      }

      .tooltip-measure {
        opacity: 1;
        font-weight: bold;
      }

      .tooltip-static {
        background-color: #ffcc33;
        color: black;
        border: 1px solid white;
      }

      .tooltip-measure:before,
      .tooltip-static:before {
        border-top: 6px solid rgba(0, 0, 0, 0.5);
        border-right: 6px solid transparent;
        border-left: 6px solid transparent;
        content: "";
        position: absolute;
        bottom: -6px;
        margin-left: -7px;
        left: 50%;
      }

      .tooltip-static:before {
        border-top-color: #ffcc33;
      }
    </style>
  </head>

  <body>
    <div id="map" class="map"></div>
      <form class="layui-form">
        <div id="layerControl">
          <ul id="layerTree" class="layerTree" style="list-style: none"></ul>
        </div>
        <div id="measureType">
          <label>测量类型 &nbsp;</label>
          <select id="type">
            <option value="length">长度测量</option>
            <option value="area">面积测量</option>
          </select>
        </div>
      </form>

    <script>
      var layer = new Array(); //图层数组
      var layerName = new Array(); //图层名称数组
      var layerVisibility = new Array(); //图层可见数组
      function loadLayersControl(map, id) {
        var treeContent = document.getElementById(id);
        var layers = map.getLayers(); //获取地图中的所有图层
        for (var i = 0; i < layers.getLength(); i++) {
          layer[i] = layers.item(i);
          layerName[i] = layer[i].get("name");
          layerVisibility[i] = layer[i].getVisible(); //获取每个图层的名称及是否可见
          var elementLi = document.createElement("li");
          treeContent.appendChild(elementLi);
          var elementInput = document.createElement("input");
          elementInput.type = "checkbox";
          elementInput.name = "layers";
          elementLi.appendChild(elementInput);
          var elementLabel = document.createElement("label");
          elementLabel.className = "layer";
          setInnerText(elementLabel, layerName[i]);
          elementLi.appendChild(elementLabel);
          //<ul><li><input type="checkbox" name="layers"/><label class="layer"></label></li></ul>
          if (layerVisibility[i]) {
            elementInput.checked = true;
          }
          addChangeEvent(elementInput, layer[i]);
        }
      }

      function addChangeEvent(element, layer) {
        element.onclick = function() {
          if (element.checked) {
            layer.setVisible(true);
          } else {
            layer.setVisible(false);
          }
        };
      }
      function setInnerText(element, text) {
        if (typeof element.textContent == "string") {
          element.textContent = text;
        } else {
          element.innerText = text; //FireFox不支持innerText方法,兼容
        }
      }

      var pointStyle = new ol.style.Style({
        /*icon样式*/
        image: new ol.style.Icon(
          /** @type {olx.style.IconOptions} */ ({
            opacity: 0.95,
            src: "${pageContext.request.contextPath}/images/point_geo.png"
          })
        )
      });

      //读取水库信息
      $.get(
        "${pageContext.request.contextPath}/data/reservoir.geojson",
        function(data) {
          addGeoReservoirJson(data);
        },
        "json"
      );
      function addGeoReservoirJson(data) {
        var vectorSource = new ol.source.Vector({
          features: new ol.format.GeoJSON().readFeatures(data)
        });
        var surfaceLayer = new ol.layer.Vector({
          source: vectorSource,
          style: new ol.style.Style({
            stroke: new ol.style.Stroke({
              color: "#ff0000",
              width: 3
            }),
            radius: 10,
            fill: new ol.style.Fill({
              color: "#ffff00"
            })
          }),
          name: "水库"
        });
        map.addLayer(surfaceLayer);
      }

      //读取取水口信息
      $.get(
        "${pageContext.request.contextPath}/data/waterintake.geojson",
        function(data) {
          addWaterIntakeJson(data);
        },
        "json"
      );
      function addWaterIntakeJson(data) {
        var vectorSource = new ol.source.Vector({
          features: new ol.format.GeoJSON().readFeatures(data)
        });
        var waterIntakeLayer = new ol.layer.Vector({
          source: vectorSource,
          style: pointStyle,
          name: "取水口"
        });
        map.addLayer(waterIntakeLayer);
      }

      //读取渠道信息
      $.get(
        "${pageContext.request.contextPath}/data/channel.geojson",
        function(data) {
          addChannelJson(data);
        },
        "json"
      );
      function addChannelJson(data) {
        var vectorSource = new ol.source.Vector({
          features: new ol.format.GeoJSON().readFeatures(data)
        });
        var channelLayer = new ol.layer.Vector({
          source: vectorSource,
          style: new ol.style.Style({
            stroke: new ol.style.Stroke({
              color: "#0000ff",
              width: 3
            })
          }),
          name: "渠道"
        });
        map.addLayer(channelLayer);
      }

      //读取保护区信息
      $.post(
              "${pageContext.request.contextPath}/getReserveGeom.action",
              function (data) {
                addReserveJson(data);
              },
              "json"
      );
      function addReserveJson(data) {
        var vectorSource = new ol.source.Vector({
          features: (new ol.format.GeoJSON()).readFeatures(data)
        });
        var reserveLayer = new ol.layer.Vector({
          source: vectorSource,
          style: new ol.style.Style({
            stroke: new ol.style.Stroke({
              color: '#0000ff',
              width: 3
            })
          }),
          name: '渠道'
        });
        map.addLayer(reserveLayer);
        loadLayersControl(map,"layerTree");
      }

      // var raster = new ol.layer.Tile({
      //   source: new ol.source.OSM()
      // });
      //定义矢量数据源
      var source = new ol.source.Vector();
      //定义矢量图层
      var vector = new ol.layer.Vector({
        source: source,
        style: new ol.style.Style({
          fill: new ol.style.Fill({
            color: "rgba(255, 255, 255, 0.2)"
          }),
          stroke: new ol.style.Stroke({
            color: "#ffcc33",
            width: 2
          }),
          image: new ol.style.Circle({
            radius: 7,
            fill: new ol.style.Fill({
              color: "#ffcc33"
            })
          })
        }),
        name: "自定义测量图层"
      });

      //创建一个当前要绘制的对象
      var sketch;

      //创建一个帮助提示框对象
      var helpTooltipElement;

      //创建一个测量提示框对象
      var helpTooltip;

      //创建一个测量提示框对象
      var measureTooltipElement;

      //创建一个测量提示信息对象
      var measureTooltip;

      //继续绘制多边形的提示信息
      var continuePolygonMsg = "再点击继续绘制继续绘制多边形";

      //继续绘制线段的提示信息
      var continueLineMsg = "再点击继续绘制线段";

      //鼠标移动触发的函数
      var pointerMoveHandler = function(evt) {
        //如果是平移地图则直接结束
        if (evt.dragging) {
          return;
        }
        //帮助提示信息
        var helpMsg = "点击设置测量起点";

        if (sketch) {
          //获取绘图对象的几何要素
          var geom = sketch.getGeometry();
          //如果当前绘制的几何要素是多边形，则将绘制提示信息设置为多边形绘制提示信息
          //如果当前绘制的几何要素是多线段，则将绘制提示信息设置为多线段绘制提示信息
          if (geom instanceof ol.geom.Polygon) {
            helpMsg = continuePolygonMsg;
          } else if (geom instanceof ol.geom.LineString) {
            helpMsg = continueLineMsg;
          }
        }
        //设置帮助提示要素的内标签为帮助提示信息
        helpTooltipElement.innerHTML = helpMsg;
        //设置帮助提示信息的位置
        helpTooltip.setPosition(evt.coordinate);
        //移除帮助提示要素的隐藏样式
        helpTooltipElement.classList.remove("hidden");
      };

      //获取天地图图层
      function getTdtLayer(lyr, name) {
        var urls = [];
        for (var i = 0; i < 8; i++) {
          urls.push(
            "http://t" +
              i +
              ".tianditu.com/DataServer?T=" +
              lyr +
              "&X={x}&Y={y}&L={z}&tk=a4c01359108c54c0c298e2e1c59c81c6"
          );
        }
        var layer = new ol.layer.Tile({
          source: new ol.source.XYZ({
            urls: urls
            //url: "http://t4.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=a4c01359108c54c0c298e2e1c59c81c6"
          }),
          name: name
        });
        return layer;
      }
      //初始化地图
      var map = new ol.Map({
        layers: [
          //raster,
          //加载天地图数据源
          getTdtLayer("vec_w", "天地图底图"),
          getTdtLayer("cva_w", "天地图注记"),
          vector
        ],
        target: "map",
        view: new ol.View({
          center: [118.28, 32.32],
          zoom: 14,
          projection: "EPSG:4326"
        })
      });
      //给鼠标移动添加事件监听函数
      map.on("pointermove", pointerMoveHandler);

      //当鼠标移出地图视图时为帮助提示要素添加隐藏样式
      map.getViewport().addEventListener("mouseout", function() {
        helpTooltipElement.classList.add("hidden");
      });

      //获取类型
      var typeSelect = document.getElementById("type");
      //定义一个交互式绘图对象
      var draw;

      //格式化长度输出
      var formatLength = function(line) {
        //获取初始坐标系
        var sourceProj = map.getView().getProjection();
        //克隆该几何对象然后转换坐标系
        var geom = line.clone().transform(sourceProj, "EPSG:3857");
        //console.log(geom);
        var length = ol.sphere.getLength(geom);
        var output;
        if (length > 100) {
          output = Math.round((length / 1000) * 100) / 100 + " " + "km";
        } else {
          output = Math.round(length * 100) / 100 + " " + "m";
        }
        return output;
      };

      //格式化面积输出
      var formatArea = function(polygon) {
        //获取初始坐标系
        var sourceProj = map.getView().getProjection();
        //克隆该几何对象然后转换坐标系
        var geom = polygon.clone().transform(sourceProj, "EPSG:3857");
        //console.log(sourceProj);
        var area = ol.sphere.getArea(geom);
        var output;
        if (area > 10000) {
          output =
            Math.round((area / 1000000) * 100) / 100 + " " + "km<sup>2</sup>";
        } else {
          output = Math.round(area * 100) / 100 + " " + "m<sup>2</sup>";
        }
        return output;
      };

      //添加交互式绘图对象的函数
      function addInteraction() {
        var type = typeSelect.value == "area" ? "Polygon" : "LineString";
        draw = new ol.interaction.Draw({
          source: source,
          type: type,
          style: new ol.style.Style({
            fill: new ol.style.Fill({
              color: "rgba(255, 255, 255, 0.2)"
            }),
            stroke: new ol.style.Stroke({
              color: "rgba(0, 0, 0, 0.5)",
              lineDash: [10, 10],
              width: 2
            }),
            image: new ol.style.Circle({
              radius: 5,
              stroke: new ol.style.Stroke({
                color: "rgba(0, 0, 0, 0.7)"
              }),
              fill: new ol.style.Fill({
                color: "rgba(255, 255, 255, 0.2)"
              })
            })
          })
        });
        //将交互绘图对象添加到地图中
        map.addInteraction(draw);

        //创建测量提示框
        createMeasureTooltip();
        //创建帮助提示框
        createHelpTooltip();

        //定义一个事件监听
        var listener;
        //绘制开始事件
        draw.on(
          "drawstart",
          function(evt) {
            // set sketch
            sketch = evt.feature;

            //提示框的坐标
            var tooltipCoord = evt.coordinate;

            //监听几何要素的change事件
            listener = sketch.getGeometry().on("change", function(evt) {
              //获取绘制的几何对象
              var geom = evt.target;
              // console.log(geom);
              //定义一个输出对象，用于记录面积和长度
              var output;
              if (geom instanceof ol.geom.Polygon) {
                //输出多边形的面积
                output = formatArea(geom);
                //获取多边形中心点的坐标
                tooltipCoord = geom.getInteriorPoint().getCoordinates();
              } else if (geom instanceof ol.geom.LineString) {
                //输出多线段的长度
                output = formatLength(geom);
                //获取多线段的最后一个点的坐标
                tooltipCoord = geom.getLastCoordinate();
              }
              //设置测量提示框的内标签为最终输出结果
              measureTooltipElement.innerHTML = output;
              //设置测量提示信息的位置坐标
              measureTooltip.setPosition(tooltipCoord);
            });
          },
          this
        );

        //绘制结束事件
        draw.on(
          "drawend",
          function() {
            //设置测量提示框的样式
            measureTooltipElement.className = "tooltip tooltip-static";
            //设置偏移量
            measureTooltip.setOffset([0, -7]);
            //清空绘制要素
            sketch = null;
            //清空测量提示要素
            measureTooltipElement = null;
            //创建测量提示框
            createMeasureTooltip();
            //移除事件监听
            ol.Observable(listener);
          },
          this
        );
      }

      //创建帮助提示框
      function createHelpTooltip() {
        //如果已经存在帮助提示框则移除
        if (helpTooltipElement) {
          helpTooltipElement.parentNode.removeChild(helpTooltipElement);
        }
        //创建帮助提示要素的div
        helpTooltipElement = document.createElement("div");
        //设置帮助提示要素的样式
        helpTooltipElement.className = "tooltip hidden";
        //创建一个帮助提示的覆盖标注
        helpTooltip = new ol.Overlay({
          element: helpTooltipElement,
          offset: [15, 0],
          positioning: "center-left"
        });
        //将帮助提示的覆盖标注添加到地图中
        map.addOverlay(helpTooltip);
      }

      //创建测量提示框
      function createMeasureTooltip() {
        //如果已经存在测量提示框则移除
        if (measureTooltipElement) {
          measureTooltipElement.parentNode.removeChild(measureTooltipElement);
        }
        //创建测量提示框的div
        measureTooltipElement = document.createElement("div");
        //设置测量提示要素的样式
        measureTooltipElement.className = "tooltip tooltip-measure";
        //创建一个测量提示的覆盖标注
        measureTooltip = new ol.Overlay({
          element: measureTooltipElement,
          offset: [0, -15],
          positioning: "bottom-center"
        });
        //将测量提示的覆盖标注添加到地图中
        map.addOverlay(measureTooltip);
      }

      //测量类型发生改变时触发事件
      typeSelect.onchange = function() {
        //移除之前的绘制对象
        map.removeInteraction(draw);
        //重新进行绘制
        addInteraction();
      };

      addInteraction();
    </script>
  </body>
</html>
